﻿' Il modello di elemento per il controllo utente è documentato all'indirizzo http://go.microsoft.com/fwlink/?LinkId=234236

Public NotInheritable Class AnalogicGamePad
    Inherits UserControl
    Implements IDisposable

    Private WithEvents StickControl As New Stick
    Private isStickHolding As Boolean

#Region "EVENT DECLARATIONS"

    Public Event StickPositionChanged(horizontalValue As Integer, verticalValue As Integer)

#End Region

#Region "CONSTRUCTOR"

    Public Sub New()

        ' Chiamata richiesta dalla finestra di progettazione.
        InitializeComponent()

        StickControl.Style = Me.Resources("GamePadButtonStyle")
        Me.gamePadCanvas.Children.Add(StickControl)

    End Sub

#End Region

#Region "EVENTS"

    Private Sub Stick_StickPressed(sender As Object) Handles StickControl.StickPressed

        Me.isStickHolding = True

    End Sub

    Private Sub Stick_StickReleased(sender As Object) Handles StickControl.StickReleased

        Me.isStickHolding = False

        Canvas.SetLeft(Me.StickControl, 50)
        Canvas.SetTop(Me.StickControl, 50)

        RaiseEvent StickPositionChanged(0, 0)

    End Sub

    Private Sub Canvas_PointerMoved(sender As Object, e As PointerRoutedEventArgs) Handles gamePadCanvas.PointerMoved

        Dim p As Point = e.GetCurrentPoint(sender).Position
        Dim horizontalValue As Integer = 0
        Dim verticalValue As Integer = 0
        Dim valueChanged As Boolean = False

        If Me.isStickHolding = True Then

            If p.X >= (Me.StickControl.Width / 2) AndAlso p.X <= Me.gamePadCanvas.Width - (Me.StickControl.Width / 2) Then
                If Me.StickControl.GetValue(Canvas.LeftProperty) <= Me.gamePadCanvas.Width - Me.StickControl.Width _
                    AndAlso Me.StickControl.GetValue(Canvas.LeftProperty) >= 0 Then
                    Canvas.SetLeft(Me.StickControl, p.X - (Me.StickControl.Width / 2))
                ElseIf Me.StickControl.GetValue(Canvas.LeftProperty) > Me.gamePadCanvas.Width - Me.StickControl.Width Then
                    Canvas.SetLeft(Me.StickControl, Me.gamePadCanvas.Width - Me.StickControl.Width)
                ElseIf Me.StickControl.GetValue(Canvas.LeftProperty) < 0 Then
                    Canvas.SetLeft(Me.StickControl, 0)
                End If

                valueChanged = True

            End If

            If p.Y >= (Me.StickControl.Height / 2) AndAlso p.Y <= Me.gamePadCanvas.Height - (Me.StickControl.Height / 2) Then
                If Me.StickControl.GetValue(Canvas.TopProperty) <= Me.gamePadCanvas.Height - Me.StickControl.Height _
                    AndAlso Me.StickControl.GetValue(Canvas.TopProperty) >= 0 Then
                    Canvas.SetTop(Me.StickControl, p.Y - (Me.StickControl.Height / 2))
                ElseIf Me.StickControl.GetValue(Canvas.TopProperty) > Me.gamePadCanvas.Height - Me.StickControl.Height Then
                    Canvas.SetTop(Me.StickControl, Me.gamePadCanvas.Height - Me.StickControl.Height)
                ElseIf Me.StickControl.GetValue(Canvas.TopProperty) < 0 Then
                    Canvas.SetTop(Me.StickControl, 0)
                End If

                valueChanged = True

            End If


            If valueChanged = True Then
                RaiseEvent StickPositionChanged(Me.StickControl.GetValue(Canvas.LeftProperty) - 50, Me.StickControl.GetValue(Canvas.TopProperty) - 50)
            End If

        End If

    End Sub

#End Region

#Region "IDisposable Support"
    Private disposedValue As Boolean ' Per rilevare chiamate ridondanti

    ' IDisposable
    Protected Sub Dispose(disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                ' TODO: eliminare stato gestito (oggetti gestiti).
            End If

            ' TODO: liberare risorse non gestite (oggetti non gestiti) ed eseguire l'override del seguente Finalize().
            ' TODO: impostare campi di grandi dimensioni su null.
        End If
        Me.disposedValue = True
    End Sub

    ' TODO: eseguire l'override di Finalize() solo se Dispose(ByVal disposing As Boolean) dispone del codice per liberare risorse non gestite.
    'Protected Overrides Sub Finalize()
    '    ' Non modificare questo codice. Inserire il codice di pulizia in Dispose(ByVal disposing As Boolean).
    '    Dispose(False)
    '    MyBase.Finalize()
    'End Sub

    ' Questo codice è aggiunto da Visual Basic per implementare in modo corretto il modello Disposable.
    Public Sub Dispose() Implements IDisposable.Dispose
        ' Non modificare questo codice. Inserire il codice di pulizia in Dispose(disposing As Boolean).
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region

#Region "CLASSES"

    Class Stick
        Inherits Button

        Event StickPressed(sender As Object)
        Event StickReleased(sender As Object)

        Public Sub New()
            MyBase.New()

            Me.Width = 100
            Me.Height = 100

            Canvas.SetTop(Me, 50)
            Canvas.SetLeft(Me, 50)

            Me.BorderThickness = New Thickness(0)
            Me.Padding = New Thickness(0)

            Dim rect As New Shapes.Rectangle
            rect.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center
            rect.VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center
            rect.Height = 85
            rect.Width = 85
            rect.RadiusX = 60
            rect.RadiusY = 60
            rect.Stroke = New SolidColorBrush(Windows.UI.Colors.Black)
            rect.StrokeThickness = 3

            Dim lgb As New LinearGradientBrush
            lgb.StartPoint = New Point(0.5, 1)
            lgb.EndPoint = New Point(0.5, 0)
            lgb.GradientStops = New GradientStopCollection
            Dim gs As New GradientStop
            gs.Color = Windows.UI.Colors.Black
            gs.Offset = 0.1
            lgb.GradientStops.Add(gs)
            gs = New GradientStop
            gs.Color = Windows.UI.Color.FromArgb(100, 176, 176, 176)
            gs.Offset = 0.5
            lgb.GradientStops.Add(gs)
            gs = New GradientStop
            gs.Color = Windows.UI.Colors.Black
            gs.Offset = 0.9
            lgb.GradientStops.Add(gs)

            rect.Fill = lgb

            Me.Content = rect

        End Sub

        Protected Overrides Sub OnPointerPressed(e As PointerRoutedEventArgs)
            MyBase.OnPointerPressed(e)

            RaiseEvent StickPressed(Me)

            e.Handled = True
        End Sub

        Protected Overrides Sub OnPointerReleased(e As PointerRoutedEventArgs)
            MyBase.OnPointerReleased(e)

            RaiseEvent StickReleased(Me)

            e.Handled = True
        End Sub
    End Class

#End Region

End Class
